/*----------------------------------------------------------------------------
Owner(s): Shane Whitfield
$Copyright: $
$Id: 

Purpose  : 
----------------------------------------------------------------------------*/

#pragma once

#include "singleton.h"
#include "bbmath.h"
#include "subsystem.h"

/*--------------------------------------------------------------------------*/
// Class CCamera declaration.
class CCamera : public TSingleton<CCamera>, public CSubsystem
{
	typedef CSubsystem super;

public:
					CCamera();
				
	//Subsystem Overrides
	virtual void	OnPostWorldUpdate();
	virtual void	OnPostWorldLoad();
	virtual void	OnPreWorldUnload();
		
	void		SetPos(const Vector2f& i_pos);
	void		SetTargetPos(const Vector2f& i_pos);
	Vector2f	GetPos() const {
					return m_worldMat.GetPos(); }
	void		SetZoomFactor(float i_zoomFactor) {
					m_zoomFactor = i_zoomFactor; }
    float       GetZoomFactor() {
                    return m_zoomFactor;}
    
	void		Apply();
    
    Vector2f    ScreenToCameraSpace(const Vector2f& i_screenCoords);
	
	float		GetWorldWidth() const {
					return m_viewExtents.x * m_zoomFactor; }
	float		GetWorldHeight() const {
					return m_viewExtents.y * m_zoomFactor; }
	float		GetCameraStillDuration() const;
	
	// $$$ BB: (SAW) Later we should rethink this number. Its a simple guess as to 
	//		when the player begins to have trouble selecting game objects with a touch.
	bool		IsZoomedPastTouchInput() const {
					return PercentPastTouchInput() < 0.0f; }
	float		PercentPastTouchInput() const {
					return 0.8f - m_zoomFactor; }
			
private:

	enum EState
	{
		BEGIN_ENUM(EState_),
		EState_Cutting,
		EState_Smoothing,
		EState_ZoomToTatical,
		EState_ZoomToFrame,
		END_ENUM(EState_)
	};
	
	void	setState(EState i_state);
	void	clampTarget();
	bool	smoothToTargetZoom();					//returns true if at the target zoom
	bool	smoothToTargetPos();					//returns true if at the target position

	float			m_smoothSpeed;
	EState			m_state;
	Vector2f		m_targetPos;
	Transform2D		m_worldMat;
	float			m_lastRequestedZoom;			// the last zoom factor
	float			m_zoomFactor;					// the current zoom factor
	float			m_zoomTarget;					// the target to zoom to
	float			m_tLastMoved;					// the time stamp of the last time the camera was moved
    
    Vector2f        m_viewExtents;					// the view width and height
	float			m_startTouchWorldVecLength;		// start length vector of the double touch
	Vector2f		m_lastMidScreenPos;				// the last mid pos of the touch zoom
	float			m_minZoomFactor;				// the current min zoom factor
	float			m_maxZoomFactor;				// the current max zoom factor
};

inline CCamera& CCamera_GetSingleton() { return CCamera::GetSingleton(); }
#define g_camera (CCamera_GetSingleton())

/*-----------------------------------EOF!-----------------------------------*/